/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
 *
 */

import path from 'path';

import fse from 'fs-extra';

import { replacer } from './replacer.js';

/**
 * 将对象写进文件中
 *
 * @since 2022/8/25
 */
export class LocalFileWriter {
  private static instance: LocalFileWriter;
  private _space: number;
  private _replacer: (this: any, key: string, value: any) => any = replacer;

  private constructor() {
    this._space = 2;
  }

  withSpace(space: number) {
    this._space = space;
  }

  withReplacer(replacer: (this: any, key: string, value: any) => any) {
    this._replacer = replacer;
  }

  /**
   * 将object对象写进json文件中
   *
   * @param filePath
   * @param content
   */
  write(filePath: string, content: { [key: string]: any }) {
    try {
      const fileContentStr = JSON.stringify(content, this._replacer, this._space);
      this.writeStr(filePath, fileContentStr);
    } catch (err) {
      const fileContentStrArr = this.chunkStringify(content);
      this.writeStrArr(filePath, fileContentStrArr);
    }
  }
  chunkStringify(content: { [key: string]: any }) {
    // 超过2的29次方会报错，大约5.3亿+
    const MAX_LENGTH = 100000000;
    const keys = Object.keys(content);
    const res = ['{\n'];
    // 缩进的空格字符串
    const spaceStr = new Array(this._space).fill(' ').join('');
    keys.forEach((key) => {
      if (Array.isArray(content[key]) && content[key].length) {
        res.push(`${spaceStr}${JSON.stringify(key)}: [\n`);
        // 循环数据，超过最大长度push
        let resStr = '';
        for (let i = 0; i < content[key].length; i++) {
          const item = content[key][i];
          const itemStr = `${JSON.stringify(item, this._replacer, this._space)
            .split('\n')
            .map((str) => `${spaceStr}${spaceStr}${str}`)
            .join('\n')},\n`;
          if (resStr.length >= MAX_LENGTH) {
            res.push(resStr);
            resStr = itemStr;
          } else {
            resStr += itemStr;
          }
        }
        // 去掉末尾逗号
        res.push(`${resStr.replace(/,\n$/, '\n')}${spaceStr}],\n`);
      } else {
        res.push(`${spaceStr}${JSON.stringify(key)}: ${JSON.stringify(content[key], this._replacer, this._space)},\n`);
      }
    });
    // 去掉末尾逗号
    res[res.length - 1] = res[res.length - 1].replace(/,\n$/, '\n');
    res.push('}');
    return res;
  }

  writeStr(filePath: string, content: string) {
    const dir = path.dirname(filePath);
    if (!fse.existsSync(dir)) {
      fse.mkdirSync(dir, { recursive: true });
    }
    fse.writeFileSync(filePath, content);
  }

  /**
   * 处理写入文件时报Invalid String length问题
   * @param filePath 文件路径
   * @param contentArray 文件内容拆分后的数组
   */
  writeStrArr(filePath: string, contentArray: string[]) {
    const dir = path.dirname(filePath);
    if (!fse.existsSync(dir)) {
      fse.mkdirSync(dir, { recursive: true });
    }
    fse.writeFileSync(filePath, '');
    contentArray.forEach((content) => {
      fse.appendFileSync(filePath, content);
    });
  }

  static getInstance() {
    if (!LocalFileWriter.instance) {
      LocalFileWriter.instance = new LocalFileWriter();
    }
    return LocalFileWriter.instance;
  }
}
